<?php


namespace app\model;


use app\services\Jwt;
use app\services\SendCode;
use app\services\UserAuthServices;
use think\Exception;
use think\exception\HttpException;
use think\exception\ValidateException;
use think\facade\App;
use think\facade\Db;
use think\Model;
use think\Request;
use utils\AES;
use utils\Define;
use utils\JwtAuth;

class User extends Model
{

    protected $autoWriteTimestamp = 'datetime';
    protected $createTime = 'created_time';
    protected $updateTime = 'updated_time';


    /**
     * 注册
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function Register($data)
    {
        if (empty($data['sign_str'])) {
            return app('json')->json_error('参数错误');
        }
        $data = AES::decrypt($data['sign_str']);
        if (empty($data)) {
            return app('json')->json_error('参数错误');
        }
        validate(\app\validate\User::class)
            ->scene('register')
            ->check($data);
        $parent = $this->where(['code' => $data['invite_code']])->find();
        if (!$parent) {
            return app('json')->json_error('邀请码不存在');
        }
        $mobile = $this->where('phone', $data['phone'])->value('phone');
        if ($mobile) {
            return app('json')->json_error('该手机号已被注册');
        }
        $sendCode = App::make(SendCode::class);
        $sendCode->CodeVerify($data['code'], $data['phone'], 1);
        //上级获取奖励
        $count = Db::name('money_log')->where(['user_id' => $parent->id, 'type' => 6])->count();
        switch (true) {
            case ($count < 1):
                $integral = 100;
                break;
            case ($count < 2):
                $integral = 150;
                break;
            default:
                $integral = 200;
        }
        Db::startTrans();
        try {
            MoneyLog::SetUserMoney($parent->id, $parent->integral, $integral, 6);
            $parent->integral += $integral;
            $parent->save();
            $data['p_id'] = $parent->id;
            $data['path'] = $parent['path'] . ',' . $parent->id;
            $data['code'] = InviteCode();
            $data['password'] = sha1($data['password']);
            $data['nickname'] = '会员:' . mt_rand(10000, 10000000);
            $this->save($data);
            Db::commit();
            return app('json')->json_success('注册成功');
        } catch (\Exception $exception) {
            Db::rollback();
            return app('json')->json_success('注册失败');
        }

    }

    /**
     * 登录
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function Login($data)
    {
        $user = app()->make(UserAuthServices::class)->UserInfo($data);
        switch ($data['cls']) {
            case 2:
                if ($user['data']['is_proxy'] == 0) {
                    return app('json')->json_error('登录失败，没有权限');
                }
                break;
            case 3:
                app()->make(SendCode::class)->CodeVerify($data['code'], $data['phone'], 3);
                break;
            case 4:
                $appId = 'wxeb5c21ccd5da270a';
                $appSecret = 'cfdde9cae42c96d518d797e50777d372';
                $code = $data['wx_code'];
                $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $appId . "&secret=" . $appSecret . "&js_code=" . $code . "&grant_type=authorization_code";
                $arr = CurlGet($url);
                $arr = json_decode($arr, true);
                if (!$arr || !$arr['session_key']) {
                    return app('json')->json_error('授权失败');
                }
                $aesIV = base64_decode($data['iv']);
                $aesCipher = base64_decode($data['encryptedData']);
                $result = openssl_decrypt($aesCipher, "AES-128-CBC", base64_decode($arr['session_key']), 1, $aesIV);
                $dataObj = json_decode($result);
                if (!$dataObj->phoneNumber) {
                    return app('json')->json_error('手机号获取失败');
                }
                $data['phone'] = $dataObj->phoneNumber;
                $user = app()->make(UserAuthServices::class)->UserInfo($data);
                $user['data']['openid'] = $arr['openid'];
                $user['data']['session_key'] = $arr['session_key'];
                break;
            default:

                validate(\app\validate\User::class)
                    ->scene('login')
                    ->check($data);
        }
        if ($user['code'] != 200) {
            return app('json')->json_error($user['msg'], $user['code']);
        }
        $user['data']['token'] = app()->make(JwtAuth::class)->createToken($user['data']['id'], $user['data']);
        LoginLog::add($user['data']['id'], $data['ip'], 1);
        return app('json')->json_success('登录成功', $user['data']);
    }


    /**
     * 微信登录
     */
    public function WxLogin($data)
    {

        //返回信息

    }


    /**
     * 用户信息
     * @param $data
     * @return mixed
     */
    public function UserInfo($data)
    {
        $user = app()->make(UserAuthServices::class)->UserInfo(['phone' => $data->user->phone], 2);
        if ($user['code'] != 200) {
            return app('json')->json_error($user['msg'], $user['code']);
        }
        return app('json')->json_success('成功', $user['data']);
    }


    /**
     * 完成实名
     * @param $user_id
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function realName($user_id, $data)
    {
        $user = $this->where(['id' => $user_id])->find();
        if (!$user) {
            return app('json')->json_error('用户不存在');
        }
        if ($user->is_real_name == 1) {
            return app('json')->json_error('您已完成实名');
        }
        //查看用户是否绑定地址并且没有得到过奖励
        $log = Db::name('money_log')->where(['user_id' => $user_id, 'type' => 4])->count();
        $address = Db::name('address')->where(['user_id' => $user_id])->count();
        $data['id'] = $user_id;
        $data['is_real_name'] = 1;
        if ($log <= 0 && $address >= 1) {
            MoneyLog::SetUserMoney($user_id, $user->integral, SystemConfig('real_name'), 4);
            $user->integral += SystemConfig('real_name');
            \app()->make(Activity::class)->NewbieRewards($user->id);
        }
        $user->save($data);
        return app('json')->json_success('实名成功');
    }


    /**
     * 验证支付密码
     * @param $data
     * @return mixed
     */
    public function verifyPayPass($data)
    {
        if (sha1($data->data['pay_pass']) != $data->user->paypass) {
            return app('json')->json_error('密码错误');
        }
        return app('json')->json_success('成功');
    }

    /**
     * 好友列表
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DbException
     */
    public function UserList($data)
    {
        $userList = Db::name('user')
            ->field('id,username,avatar,created_time')
            ->where(['p_id' => $data['user_id'], 'status' => 1])
            ->paginate($data['limit'])
            ->toArray();
        return app('json')->json_success('成功', $userList);
    }


    /**
     * 修改个人资料
     * @param $data
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function UserModify($data)
    {
        switch ($data['type']) {
            case 1://修改头像
                $data->user->avatar = $data->data['avatar'];
                break;
            case 2://修改登录密码
                app()->make(SendCode::class)->CodeVerify($data->data['code'], $data->user->phone, 2);
                if ($data['cls'] == 1) {
                    if (sha1($data->data['password']) != $data->user->password) {
                        return app('json')->json_error('密码错误');
                    }
                    if ($data->data['new_password'] != $data->data['new_password1']) {
                        return app('json')->json_error('两次密码不一致');
                    }
                    $data->user->password = sha1($data->data['new_password']);
                } else {
                    if (sha1($data->data['pay_pass']) != $data->user->paypass) {
                        return app('json')->json_error('密码错误');
                    }
                    if ($data->data['new_pay_pass'] != $data->data['new_pay_pass1']) {
                        return app('json')->json_error('两次密码不一致');
                    }
                    $data->user->paypass = sha1($data->data['new_pay_pass']);
                }
                break;
            case 3://修改账户名称
                $data->user->nickname = $data->data['nickname'];
                break;
            case 4: //忘记密码
                if (!checkPhoneNumber($data->data['phone'])) {
                    return app('json')->json_error('请填写正确的联系手机号');
                }
                $data->user = $this->where(['phone' => $data->data['phone']])->find();
                if (!$data->user) {
                    return app('json')->json_error('用户不存在');
                }
                app()->make(SendCode::class)->CodeVerify($data->data['code'], $data->user->phone, 2);
                if ($data['cls'] == 1) {
                    if ($data->data['password'] != $data->data['new_password']) {
                        return app('json')->json_error('两次密码不一致');
                    }
                    $data->user->password = sha1($data->data['password']);
                } else {
                    if ($data->data['pay_pass'] != $data->data['new_pay_pass']) {
                        return app('json')->json_error('两次密码不一致');
                    }
                    $data->user->paypass = sha1($data->data['pay_pass']);
                }
                break;
            case 5: //修改手机号
                if (!checkPhoneNumber($data->data['new_phone'])) {
                    return app('json')->json_error('请填写正确的联系手机号');
                }
                app()->make(SendCode::class)->CodeVerify($data->data['code'], $data->user->phone, 2);
                app()->make(SendCode::class)->CodeVerify($data->data['new_code'], $data->data['new_phone'], 1);
                $phone = $this->where(['phone' => $data->data['new_phone']])->find();
                if ($phone) {
                    return app('json')->json_error('手机号已存在');
                }
                $data->user->phone = $data->data['new_phone'];
                break;
            case 6: //设置支付密码
                if($data->user->paypass != ''){
                    return app('json')->json_error('您已经设置了支付密码哦~');
                }
                app()->make(SendCode::class)->CodeVerify($data->data['code'], $data->user->phone, 2);
                $data->user->paypass = sha1($data->data['pay_pass']);
                break;
        }
        $data->user->save();
        return app('json')->json_success('成功');

    }

    /**
     * 修改path
     * @param $user
     */
//    public static function onAfterInsert($user)
//    {
//        $user->path = $user->path . ',' . $user->id;
//        $user->save();
//    }


    /**
     * B端个人中心
     * @param $data
     * @return mixed
     */
//    public function PersonalCenter($data)
//    {
//        //今天开始结束时间
//        $start_time = DateTime()['t_s'];
//        $end_time = DateTime()['t_e'];
//        //下级用户总量
//        $result['total_count'] = Db::name('user')->whereFindInSet('path', $data->user->id)->count();
//        //直推用户量
//        $result['straight_count'] = Db::name('user')->where(['p_id' => $data->data['user_id']])->count();
//        //总活跃用户
//        $result['active_count'] = Db::name('user')->whereFindInSet('path', $data->user->id)->where(['is_active' => 1])->count();
//        return app('json')->json_success('成功', $result);
//    }


    /**
     * B端数据中心
     * @param $data
     * @return mixed
     */
    public function PersonalCenter($data)
    {
        $start_time = $data->data['start_time'];
        $end_time = $data->data['end_time'];
        //今天开始结束时间
        if (empty($start_time)) {
            $start_time = DateTime()['t_s'];
        }
        if (empty($end_time)) {
            $end_time = DateTime()['t_e'];
        }
        $u = Db::name('user')->whereFindInSet('path', $data->user->id);
        switch ($data['type']) {
            case 1:
                $result = Db::name('user')
                    ->field('phone,created_time,
                    username,
                    is_active')
                    ->withAttr('username', function ($value, $data) {
                        if ($value == '') {
                            return '未实名';
                        }
                    })
                    ->withAttr('is_active', function ($value, $data) {
                        if ($value == 1) {
                            return '活跃';
                        } else {
                            return '无效';
                        }
                    })
                    ->whereFindInSet('path', $data->user->id)
                    ->whereTime('created_time', 'between', [$start_time, $end_time])
                    ->paginate($data->data['limit'])
                    ->toArray();
                $result['today_count'] = Db::name('user')
                    ->whereFindInSet('path', $data->user->id)
                    ->whereTime('created_time', 'between', [$start_time, $end_time])->count();
                break;
            case 2:
                //今日活跃人数
                $result = Db::name('money_log')
                    ->alias('a')
                    ->leftJoin('user b', 'a.user_id = b.id')
                    ->field('b.phone,username,count(a.user_id) as count,a.user_id')
                    ->withAttr('username', function ($value, $data) {
                        if ($value == '') {
                            return '未实名';
                        } else {
                            return $value;
                        }
                    })
                    ->where(['a.type' => 5])
                    ->whereIn('a.user_id', $u->column('id'))
                    ->whereTime('a.created_time', 'between', [$start_time, $end_time])
                    ->group('a.user_id')
                    ->paginate($data->data['limit'])
                    ->toArray();
                if (!empty($result['data'])) {
                    foreach ($result['data'] as &$v) {
                        $v['counts'] = Db::name('money_log')->where(['type' => 5, 'user_id' => $v['user_id']])->count();
                        unset($v['user_id']);
                    }
                }
                $result['today_active_count'] = Db::name('money_log')
                    ->where(['type' => 5])
                    ->whereIn('user_id', $u->column('id'))
                    ->whereTime('created_time', 'between', [$start_time, $end_time])
                    ->group('user_id')
                    ->count();
                break;
            case 3:
                $result = Db::name('user')
                    ->field('phone,created_time,id as user_id')
                    ->where(['p_id' => $data->data['user_id']])
                    ->whereTime('created_time', 'between', [$start_time, $end_time])
                    ->paginate($data->data['limit'])
                    ->toArray();
                if (!empty($result['data'])) {
                    foreach ($result['data'] as &$v) {
                        $uu = Db::name('user')->whereFindInSet('path', $v['user_id']);
                        $v['team_register'] = $uu->count();
                        $v['today_active'] = Db::name('money_log')
                            ->where(['type' => 5])
                            ->whereIn('user_id', $uu->column('id'))
                            ->whereTime('created_time', 'between', [$start_time, $end_time])
                            ->group('user_id')
                            ->count();
                        unset($v['user_id']);
                    }
                }
                $result['today_straight_count'] = Db::name('user')
                    ->where(['p_id' => $data->data['user_id']])
                    ->whereTime('created_time', 'between', [$start_time, $end_time])
                    ->count();
                break;
        }
        //下级用户总量
        $result['total_count'] = $u->count();
        //直推用户量
        $result['straight_count'] = Db::name('user')->where(['p_id' => $data->data['user_id']])->count();
        //总活跃用户
        $result['active_count'] = $u->where(['is_active' => 1])->count();
        return app('json')->json_success('成功', $result);
    }


    /**
     * 发短信
     * @param $request
     * @return mixed
     */
    public function SendCode($request)
    {
        if (!isset($request->data['ali_verify'])) {
            $ali_verify = '';
        } else {
            $ali_verify = $request->data['ali_verify'];
        }
        app()->make(SendCode::class)->SendCode($request->data['phone'], $request->data['type'], $ali_verify);
        return app('json')->json_success('发送成功');
    }


    /**
     * 完成新手教程
     * @param $data
     * @return mixed
     */
    public function newbieTutorial($data)
    {
        try {
            $data->user->is_newbie_tutorial = 1;
            $data->user->save();
            \app()->make(Activity::class)->NewbieRewards($data->user->id);
            return app('json')->json_success('成功');
        } catch (\Exception $exception) {
            return app('json')->json_success('失败');
        }

    }

    /**
     * 退出登录
     * @param $user_id
     * @return mixed
     */
    public function Logout($user_id)
    {
        return app('json')->json_success('成功');

    }

    /**
     * 邀请链接
     * @param $user_id
     * @return mixed
     */
    public function inviteUrl($user_id)
    {
        return app('json')->json_success('成功', ['url' => 'http://www.baidu.com']);

    }
}